{
  "openapi": "3.1.0",
  "info": {
    "title": "Cloud Storage Local API",
    "description": "Manage MoreLogin cloud storage files, uploads, deletions, and file tags through the MoreLogin Local API.\n\n**Base URL**: `http://127.0.0.1:40000`\n\nLocal API paths use the `/api` prefix.\n",
    "version": "2026-09-05"
  },
  "servers": [
    {
      "url": "http://127.0.0.1:40000"
    }
  ],
  "tags": [
    {
      "name": "Cloud Storage",
      "description": "Query storage quota and usage"
    },
    {
      "name": "Cloud Storage Files",
      "description": "Query, upload, and delete cloud storage files"
    },
    {
      "name": "Cloud Storage File Tags",
      "description": "Manage tags attached to cloud storage files"
    }
  ],
  "x-tagGroups": [
    {
      "name": "Cloud Storage",
      "tags": [
        "Cloud Storage",
        "Cloud Storage Files",
        "Cloud Storage File Tags"
      ]
    }
  ],
  "paths": {
    "/api/cloudstorage/info": {
      "get": {
        "summary": "Query Cloud Storage Information",
        "description": "Return the team's Cloud Storage quota and current usage.\n\n- **Preconditions**: the team must already have a Cloud Storage record. **A team that has never had Cloud Storage provisioned gets an error, not a zero-capacity reading** — the record is created when storage is purchased, not lazily by this call.\n- **Effect**: none. Read-only. Safe to retry with bounded backoff.\n- **Units**: `capacity` and `usedCapacity` are byte counts.\n- **Accuracy**: `usedCapacity` is a running counter maintained on upload and delete, not a live sum over the file table, so it can drift from the total of `fileSize` in `/cloudstorage/file/page`.\n- **Values**: `capacityStatus` is `1` only when a positive quota is fully consumed; `isExpired` compares the expiry date to now. Files whose upload was never confirmed do not count toward `usedCapacity`.\n\nDocumented business errors: `39001`. See [Error Codes](../Getting%20Started/error-codes.md) for what each code means. Any operation can additionally return the common codes.",
        "operationId": "queryCloudStorageInfoLocal",
        "tags": [
          "Cloud Storage"
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/StorageInfoResponse"
          }
        }
      }
    },
    "/api/cloudstorage/file/page": {
      "post": {
        "summary": "Page Cloud Storage Files",
        "description": "List Cloud Storage files, page by page.\n\n- **Effect**: none. Read-only. Safe to retry with bounded backoff.\n- **Visibility**: **only files whose upload was confirmed are listed** — a file with a pre-signed URL that was never completed does not appear. Members without the all-data permission see only files they uploaded.\n- **Filtering**: `fileName` matches partially; `tagIds` is an OR match; results are ordered newest first and the order cannot be changed.\n- **Caveat**: an entry in `tagInfo` can be null when a tag was deleted while still attached to the file.",
        "operationId": "pageCloudStorageFilesLocal",
        "tags": [
          "Cloud Storage Files"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FilePageRequest"
              },
              "example": {
                "pageNo": 1,
                "pageSize": 20,
                "fileName": "report",
                "tagIds": [
                  "1800000000000001"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/FilePageResponse"
          }
        }
      }
    },
    "/api/cloudstorage/upload/init": {
      "post": {
        "summary": "Batch Request Presigned Upload URLs",
        "description": "Reserve Cloud Storage records and get pre-signed upload URLs.\n\n- **Preconditions**: the team must have a Cloud Storage record and it must not be expired. Each base file name is limited to 60 characters and must be unique both within the request and against every existing file in the team — **matched on the name without its extension**, so `a.png` collides with an existing `a.mp4`.\n- **Limits**: at most 100 uploads may sit unconfirmed at once across the team.\n- **Effect**: inserts one file record per name with an uploading status and a zero size, and returns `{id, fileName, presignedUrl}` for each.\n- **Quota**: **space is not checked here.** It is charged when you confirm the upload, so init can succeed and complete can still fail for lack of space.\n- **Completion**: synchronous. **Each pre-signed URL is valid for one hour**; `PUT` the bytes to it, then call `/cloudstorage/upload/complete`.\n\nDocumented business errors: `39001`, `39037`, `39044`, `39045`, `39047`, `39050`, `39051`. See [Error Codes](../Getting%20Started/error-codes.md) for what each code means. Any operation can additionally return the common codes.",
        "operationId": "batchRequestCloudStoragePresignedUploadUrlsLocal",
        "tags": [
          "Cloud Storage Files"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UploadInitRequest"
              },
              "example": {
                "fileNames": [
                  "example.jpg"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/UploadInitResponse"
          }
        }
      }
    },
    "/api/cloudstorage/upload/complete": {
      "post": {
        "summary": "Confirm Upload Completion",
        "description": "Confirm an uploaded Cloud Storage file.\n\n- **Preconditions**: the file record must belong to your team and the object must already be in storage — the service reads its ETag and length to verify. Size must be greater than 0 and under 2 GB.\n- **Effect**: charges the team's storage quota atomically, then marks the record uploaded and stores the real size. Until this succeeds the file **does not appear in `/cloudstorage/file/page`** and keeps occupying one of the 100 pending slots.\n- **On failure the uploaded object is deleted.** Calling this too early, over the size limit, or with no space left removes the bytes from storage and leaves the record unconfirmed. Recovery is a fresh `/cloudstorage/upload/init` and a re-upload, not a retry of this call.\n- **Completion**: synchronous and idempotent once it has succeeded — a second call returns the same file without charging quota again.\n- **Note**: a record that is never confirmed is cleaned up automatically after 24 hours.\n\nDocumented business errors: `39001`, `39011`, `39014`, `39041`, `39046`, `39047`. See [Error Codes](../Getting%20Started/error-codes.md) for what each code means. Any operation can additionally return the common codes.",
        "operationId": "confirmCloudStorageUploadCompleteLocal",
        "tags": [
          "Cloud Storage Files"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UploadCompleteRequest"
              },
              "example": {
                "id": "1800000000000001"
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/UploadCompleteResponse"
          }
        }
      }
    },
    "/api/cloudstorage/file/delete/batch": {
      "post": {
        "summary": "Batch Delete Cloud Storage Files",
        "description": "Delete Cloud Storage files by id.\n\n- **Preconditions**: every id must resolve within your team; **the whole batch is rejected and rolled back if any one does not**, including ids that were already deleted.\n- **Effect**: a soft delete. Quota is released in the same transaction, and the stored objects are removed on a best-effort basis — a storage failure is logged but does not fail the call, so an object can outlive its record. Tag assignments are not cleaned up.\n- **Completion**: synchronous. Confirm released space with `/cloudstorage/info`.\n\nDocumented business errors: `39011`. See [Error Codes](../Getting%20Started/error-codes.md) for what each code means. Any operation can additionally return the common codes.",
        "operationId": "batchDeleteCloudStorageFilesLocal",
        "tags": [
          "Cloud Storage Files"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FileDeleteRequest"
              },
              "example": {
                "ids": [
                  "1800000000001001",
                  "1800000000001002"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/VoidDataResponse"
          }
        }
      }
    },
    "/api/cloudstorage/file/tag/set": {
      "post": {
        "summary": "Set File Tags",
        "description": "Replace the tags on a Cloud Storage file.\n\n- **Preconditions**: one `fileId` per call, and `tagIds` must be non-empty and reference Cloud Storage tags belonging to your team. Profile tags are rejected.\n- **Effect**: tags not present in the request are removed from the file and missing ones are added. **There is no way to clear all tags here** because an empty list is rejected.\n- **Completion**: synchronous and idempotent for the same body.\n\nDocumented business errors: `39011`, `39048`, `39049`. See [Error Codes](../Getting%20Started/error-codes.md) for what each code means. Any operation can additionally return the common codes.",
        "operationId": "setCloudStorageFileTagsLocal",
        "tags": [
          "Cloud Storage File Tags"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FileTagChangeRequest"
              },
              "example": {
                "fileId": "1800000000001001",
                "tagIds": [
                  "1800000000000101",
                  "1800000000000102"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/VoidDataResponse"
          }
        }
      }
    },
    "/api/cloudstorage/file/tag/add": {
      "post": {
        "summary": "Add File Tags",
        "description": "Add tags to a Cloud Storage file without removing existing ones.\n\n- **Preconditions**: one `fileId` per call, and `tagIds` must be non-empty and reference Cloud Storage tags belonging to your team.\n- **Effect**: only adds; existing tags are left in place. Use the set variant to replace them.\n- **Completion**: synchronous and idempotent — adding a tag the file already has changes nothing.\n\nDocumented business errors: `39011`, `39048`, `39049`. See [Error Codes](../Getting%20Started/error-codes.md) for what each code means. Any operation can additionally return the common codes.",
        "operationId": "addCloudStorageFileTagsLocal",
        "tags": [
          "Cloud Storage File Tags"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FileTagChangeRequest"
              },
              "example": {
                "fileId": "1800000000001001",
                "tagIds": [
                  "1800000000000103"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/VoidDataResponse"
          }
        }
      }
    },
    "/api/cloudstorage/file/tag/query": {
      "post": {
        "summary": "Query File Tags",
        "description": "Return the tags attached to one or more Cloud Storage files.\n\n- **Preconditions**: every `fileId` must resolve within your team; **one unknown id fails the whole call** rather than returning partial data.\n- **Effect**: none. Read-only. Safe to retry with bounded backoff.\n- **Caveat**: `tagIds` is read from the assignments while the tag details come from live tags, so a tag deleted while still attached appears in `tagIds` with no matching entry in the details. The two can differ in length.",
        "operationId": "queryCloudStorageFileTagsLocal",
        "tags": [
          "Cloud Storage File Tags"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FileTagQueryRequest"
              },
              "example": {
                "fileIds": [
                  "1800000000001001"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/FileTagsResponse"
          }
        }
      }
    },
    "/api/cloudstorage/tag/all": {
      "get": {
        "summary": "Query All Cloud Storage File Tags",
        "description": "Return every Cloud Storage file tag in the team.\n\n- **Effect**: none. Read-only. Safe to retry with bounded backoff.\n- **Note**: not paginated, and Cloud Storage tags have no server-side count limit, so the response grows with the number of tags your team creates.",
        "operationId": "queryAllCloudStorageFileTagsLocal",
        "tags": [
          "Cloud Storage File Tags"
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/TagListResponse"
          }
        }
      }
    },
    "/api/cloudstorage/tag/create": {
      "post": {
        "summary": "Create Cloud Storage File Tag",
        "description": "Create a Cloud Storage file tag.\n\n- **Preconditions**: `tagName` must not be blank.\n- **Effect**: creates the tag with a colour picked from a fixed palette. **Names are not checked for duplicates and there is no count limit**, so repeating the call creates a second tag with the same name.\n- **Completion**: synchronous; the response carries the new tag.",
        "operationId": "createCloudStorageFileTagLocal",
        "tags": [
          "Cloud Storage File Tags"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TagCreateRequest"
              },
              "example": {
                "tagName": "Invoice"
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/TagResponse"
          }
        }
      }
    },
    "/api/cloudstorage/tag/edit": {
      "post": {
        "summary": "Edit Cloud Storage File Tag",
        "description": "Rename a Cloud Storage file tag.\n\n- **Preconditions**: the tag must exist in your team and be a Cloud Storage tag.\n- **Effect**: only the name changes; the colour and every existing assignment are kept, so files show the new name immediately.\n- **Completion**: synchronous. No optimistic locking — concurrent renames are last-write-wins.",
        "operationId": "editCloudStorageFileTagLocal",
        "tags": [
          "Cloud Storage File Tags"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TagEditRequest"
              },
              "example": {
                "id": "1800000000000101",
                "tagName": "Invoice 2026"
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/BooleanDataResponse"
          }
        }
      }
    },
    "/api/cloudstorage/tag/delete/batch": {
      "post": {
        "summary": "Delete Cloud Storage File Tags",
        "description": "Delete Cloud Storage file tags.\n\n- **Preconditions**: every id must be a Cloud Storage tag in your team; **one invalid id fails the whole batch**.\n- **Effect**: the tags are deleted but **their file assignments are not cleaned up**. Two consequences to expect: `/cloudstorage/file/tag/query` keeps returning the deleted tag id with no matching detail, and `tagInfo` in `/cloudstorage/file/page` can contain null entries. Filtering files by a deleted tag id returns nothing.\n- **Completion**: synchronous, and not wrapped in a transaction.",
        "operationId": "deleteCloudStorageFileTagsLocal",
        "tags": [
          "Cloud Storage File Tags"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TagDeleteRequest"
              },
              "example": {
                "ids": [
                  "1800000000000101"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/BooleanDataResponse"
          }
        }
      }
    }
  },
  "security": [],
  "components": {
    "schemas": {
      "ApiResponseBase": {
        "type": "object",
        "properties": {
          "code": {
            "type": "integer",
            "description": "Return result code. `0` means success; other codes indicate exceptions.",
            "example": 0
          },
          "msg": {
            "type": [
              "string",
              "null"
            ],
            "description": "Error message.",
            "example": null
          },
          "requestId": {
            "type": "string",
            "description": "Operation request ID. This field may be present when the request passes through the API gateway.",
            "example": "1d4f3ea968664593860b94b35d4ebf5e"
          }
        },
        "required": [
          "code",
          "msg"
        ]
      },
      "StorageInfo": {
        "type": "object",
        "properties": {
          "capacity": {
            "type": "string",
            "description": "Total cloud storage capacity in bytes.",
            "example": "10737418240"
          },
          "usedCapacity": {
            "type": "string",
            "description": "Used cloud storage capacity in bytes.",
            "example": "536870912"
          },
          "expireDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
            "description": "Cloud storage expiration date."
          },
          "capacityStatus": {
            "type": "integer",
            "description": "Capacity status: 0 = normal, 1 = full.",
            "example": 0
          },
          "isExpired": {
            "type": "boolean",
            "description": "Whether the subscription plan has expired.",
            "example": false
          }
        }
      },
      "FilePageRequest": {
        "type": "object",
        "properties": {
          "pageNo": {
            "type": "integer",
            "description": "Current page number, starting from 1. Default is 1.",
            "minimum": 1,
            "default": 1,
            "example": 1
          },
          "pageSize": {
            "type": "integer",
            "description": "Number of items per page. Default is 10.",
            "minimum": 1,
            "default": 10,
            "example": 20
          },
          "fileName": {
            "type": "string",
            "description": "File name keyword for fuzzy search.",
            "example": "report"
          },
          "tagIds": {
            "type": "array",
            "description": "Filter files by tag IDs.",
            "items": {
              "type": "string"
            },
            "example": [
              "1800000000000101"
            ]
          },
          "fileType": {
            "type": "integer",
            "description": "File type filter: 0 = image, 1 = video, 2 = application, 3 = audio, 4 = document, 5 = other.",
            "example": 0
          },
          "fileIds": {
            "type": "array",
            "description": "Filter files by file IDs.",
            "items": {
              "type": "string"
            },
            "example": [
              "1800000000001001"
            ]
          }
        }
      },
      "TagInfo": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Tag ID.",
            "example": "1800000000000101"
          },
          "tagSource": {
            "type": "string",
            "description": "Tag source, e.g. ENV, PROXY.",
            "example": "ENV"
          },
          "tagName": {
            "type": "string",
            "description": "Tag name.",
            "example": "Invoice"
          },
          "tagType": {
            "type": "string",
            "description": "Tag type: TAG or GROUP.",
            "example": "TAG"
          },
          "tagIcon": {
            "type": "string",
            "description": "Tag icon.",
            "example": ""
          }
        }
      },
      "CloudStorageFile": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Cloud storage file ID.",
            "example": "1800000000001001"
          },
          "fileName": {
            "type": "string",
            "description": "File name (without extension).",
            "example": "example"
          },
          "fileExt": {
            "type": "string",
            "description": "File extension.",
            "example": "jpg"
          },
          "fileSize": {
            "type": "string",
            "description": "File size in bytes.",
            "example": "204800"
          },
          "fileType": {
            "type": "integer",
            "description": "File type: 0 = image, 1 = video, 2 = application, 3 = audio, 4 = document, 5 = other.",
            "example": 0
          },
          "tagInfo": {
            "type": "array",
            "description": "Tag details attached to the file.",
            "items": {
              "$ref": "#/components/schemas/TagInfo"
            }
          },
          "createDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
            "description": "Upload time."
          },
          "updateDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
            "description": "Update time."
          }
        }
      },
      "FilePageData": {
        "type": "object",
        "properties": {
          "current": {
            "type": "string",
            "example": "1"
          },
          "pages": {
            "type": "string",
            "example": "7"
          },
          "total": {
            "type": "string",
            "example": "128"
          },
          "dataList": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CloudStorageFile"
            }
          }
        },
        "required": [
          "current",
          "pages",
          "total",
          "dataList"
        ]
      },
      "UploadInitRequest": {
        "type": "object",
        "properties": {
          "fileNames": {
            "type": "array",
            "minItems": 1,
            "description": "List of file names to upload (with extensions), e.g. photo.jpg, video.mp4.",
            "items": {
              "type": "string"
            },
            "example": [
              "photo.jpg",
              "video.mp4"
            ]
          }
        },
        "required": [
          "fileNames"
        ]
      },
      "UploadInitResult": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Cloud storage file ID.",
            "example": "1800000000000001"
          },
          "fileName": {
            "type": "string",
            "description": "File name (with extension).",
            "example": "photo.jpg"
          },
          "presignedUrl": {
            "type": "string",
            "description": "S3 presigned upload URL. Use HTTPS PUT to upload the file content.",
            "example": "https://example.com/presigned-upload-url"
          }
        }
      },
      "UploadCompleteRequest": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Cloud storage file ID returned by the presigned upload URL API.",
            "example": "1800000000000001"
          }
        },
        "required": [
          "id"
        ]
      },
      "FileDeleteRequest": {
        "type": "object",
        "properties": {
          "ids": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "string"
            },
            "description": "Cloud storage file IDs to delete.",
            "example": [
              "1800000000001001",
              "1800000000001002"
            ]
          }
        },
        "required": [
          "ids"
        ]
      },
      "FileTagChangeRequest": {
        "type": "object",
        "properties": {
          "fileId": {
            "type": "string",
            "description": "Cloud storage file ID.",
            "example": "1800000000001001"
          },
          "tagIds": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "string"
            },
            "description": "Tag IDs.",
            "example": [
              "1800000000000101",
              "1800000000000102"
            ]
          }
        },
        "required": [
          "fileId",
          "tagIds"
        ]
      },
      "FileTagQueryRequest": {
        "type": "object",
        "properties": {
          "fileIds": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "string"
            },
            "description": "Cloud storage file IDs.",
            "example": [
              "1800000000001001"
            ]
          }
        },
        "required": [
          "fileIds"
        ]
      },
      "FileTagResultData": {
        "type": "object",
        "properties": {
          "fileId": {
            "type": "string",
            "description": "Cloud storage file ID.",
            "example": "1800000000001001"
          },
          "tagIds": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Tag IDs attached to the file.",
            "example": [
              "1800000000000101"
            ]
          },
          "tagInfo": {
            "type": "array",
            "description": "Tag details.",
            "items": {
              "$ref": "#/components/schemas/TagInfo"
            }
          }
        }
      },
      "TagCreateRequest": {
        "type": "object",
        "properties": {
          "tagName": {
            "type": "string",
            "description": "Tag name.",
            "example": "Invoice"
          }
        },
        "required": [
          "tagName"
        ]
      },
      "TagEditRequest": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Tag ID.",
            "example": "1800000000000101"
          },
          "tagName": {
            "type": "string",
            "description": "Tag name.",
            "example": "Invoice 2026"
          }
        },
        "required": [
          "id",
          "tagName"
        ]
      },
      "TagDeleteRequest": {
        "type": "object",
        "properties": {
          "ids": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "string"
            },
            "description": "Tag IDs to delete.",
            "example": [
              "1800000000000101"
            ]
          }
        },
        "required": [
          "ids"
        ]
      }
    },
    "responses": {
      "StorageInfoResponse": {
        "description": "Success",
        "content": {
          "application/json": {
            "schema": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/ApiResponseBase"
                },
                {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/StorageInfo"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              ]
            }
          }
        }
      },
      "FilePageResponse": {
        "description": "Success",
        "content": {
          "application/json": {
            "schema": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/ApiResponseBase"
                },
                {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/FilePageData"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              ]
            }
          }
        }
      },
      "UploadInitResponse": {
        "description": "Success",
        "content": {
          "application/json": {
            "schema": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/ApiResponseBase"
                },
                {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/UploadInitResult"
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              ]
            }
          }
        }
      },
      "UploadCompleteResponse": {
        "description": "Success",
        "content": {
          "application/json": {
            "schema": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/ApiResponseBase"
                },
                {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/CloudStorageFile"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              ]
            }
          }
        }
      },
      "VoidDataResponse": {
        "description": "Success",
        "content": {
          "application/json": {
            "schema": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/ApiResponseBase"
                },
                {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "null",
                      "example": null
                    }
                  }
                }
              ]
            }
          }
        }
      },
      "FileTagsResponse": {
        "description": "Success",
        "content": {
          "application/json": {
            "schema": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/ApiResponseBase"
                },
                {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/FileTagResultData"
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              ]
            }
          }
        }
      },
      "TagListResponse": {
        "description": "Success",
        "content": {
          "application/json": {
            "schema": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/ApiResponseBase"
                },
                {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TagInfo"
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              ]
            }
          }
        }
      },
      "TagResponse": {
        "description": "Success",
        "content": {
          "application/json": {
            "schema": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/ApiResponseBase"
                },
                {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/TagInfo"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              ]
            }
          }
        }
      },
      "BooleanDataResponse": {
        "description": "Success",
        "content": {
          "application/json": {
            "schema": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/ApiResponseBase"
                },
                {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "boolean",
                      "example": true
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              ]
            }
          }
        }
      }
    }
  }
}